package processor;

import java.util.Date;

import org.apache.commons.lang3.StringUtils;

import play.db.jpa.JPA;
import play.libs.F.Callback0;
import prefix.duydo.repository.JpaRepository;
import prefix.loan.util.LoanMaturity;
import prefix.platform.Constants;
import prefix.util.JPAUtil;
import models.Actor;
import models.Loan;
import models.LoanApp;
import models.LoanApp.LoanPurpose;
import models.LoanApp.LoanType;
import models.LoanApp.PaymentMethod;
import models.LoanApp.Status;

import repository.LoanRepository;
import service.ActorService;
import service.LoanService;
import service.exception.LoanAppException;
import service.exception.LoanAppException.CODE;
import service.impl.LoanAppServiceImpl;

public class LoanAppProcessor extends LoanAppServiceImpl {

    public LoanAppProcessor(LoanApp loanApp) {
        super(loanApp);
    }

    public void createLoanApp(ActorService actor, LoanPurpose purpose, LoanType loanType, double desiredAmount,
            LoanMaturity maturity, PaymentMethod paymentMethod) throws LoanAppException {
        try {
            JPAUtil.beginTransaction();
            this.dbloanApp.setAid(actor.getDBActor().getId());
            this.dbloanApp.setPurpose(purpose.ordinal());
            this.dbloanApp.setLoanType(loanType);
            this.dbloanApp.setAmount(desiredAmount);
            this.dbloanApp.setDuration(maturity.getMaturity());
            this.dbloanApp.setPaymentMode(paymentMethod);
            this.dbloanApp.setCreateD(new Date());
            this.dbloanApp.setStatus(LoanApp.Status.NONE);
            // this.dbloanApp.setProgId(null);
            // this.dbloanApp.setLoanId(null);
            JPAUtil.em().persist(this.dbloanApp);
            JPAUtil.commitTransaction();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new LoanAppException(CODE.UNKNOWN, e);
        } finally {
            JPAUtil.closeEM();
        }

    }

    public void updateLoanAppInfo(LoanPurpose purpose, LoanType loanType, double amount, int duration,
            PaymentMethod paymentMethod) throws LoanAppException {
        try {
            JPAUtil.beginTransaction();
            this.dbloanApp.setValues(purpose, loanType, amount, duration, paymentMethod);
            this.dbloanApp.setUpdateD(new Date());
            JPAUtil.em().merge(this.dbloanApp);
            JPAUtil.commitTransaction();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new LoanAppException(CODE.UNKNOWN, e);
        } finally {
            JPAUtil.closeEM();
        }
    }

    public void submitLoanApp(String loanTitle, String description) throws LoanAppException {
        try {
            JPAUtil.beginTransaction();
            this.dbloanApp.setName(loanTitle);
            this.dbloanApp.setDescription(description);
            this.dbloanApp.setAppD(new Date());
            // submit loan
            Loan loan = new Loan();
            loan.setAid(this.dbloanApp.getAid());
            loan.setLoanAppId(this.dbloanApp.getId());
            loan.setAppAmount(this.dbloanApp.getAmount());
            loan.setName(this.dbloanApp.getName());
            loan.setAppDuration(this.dbloanApp.getDuration());
            loan.setIntRate(0.0);
            loan.setLoanType(this.dbloanApp.getLoanType());
            loan.setStatus(Loan.Status.NEW);
            loan.setAppDuration(this.dbloanApp.getDuration());
            JPAUtil.em().persist(loan);
            Date now = new Date();
            this.dbloanApp.setAppD(now);
            this.dbloanApp.setAppExpireD(new Date(now.getTime() + Constants.LOAN_APP_DURATION));
            this.dbloanApp.setStatus(LoanApp.Status.SUBMITTED);
            this.dbloanApp.setLoanId(loan.getId());
            JPAUtil.em().merge(this.dbloanApp);
            JPAUtil.commitTransaction();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            throw new LoanAppException(CODE.UNKNOWN, e);
        } finally {
            JPAUtil.closeEM();
        }

    }

    public void approveLoanApp() throws LoanAppException {
        try {
            JPAUtil.beginTransaction();
            LoanService loanService = LoanRepository.getLoanByApp(this.dbloanApp.getId());
            if (loanService.getDbloan().getStatus() != Loan.Status.REVIEW_FINAL)
                throw new LoanAppException(CODE.INVALIDE_STATUS);
            if (loanService.getDbloan().getAppAmount() != loanService.getDbloan().getAmount())
                throw new LoanAppException(CODE.INVALID_AMOUNT);
            if (this.dbloanApp.getStatus() != LoanApp.Status.SUBMITTED)
                throw new LoanAppException(CODE.INVALIDE_STATUS);
            this.dbloanApp.setStatus(Status.APPROVED_CR);
            this.dbloanApp.setStatusD(new Date());
            JPAUtil.commitTransaction();
        } catch (LoanAppException e) {
            throw e;
        } catch (Exception e) {
            throw new LoanAppException(CODE.UNKNOWN, e);
        } finally {
            JPAUtil.closeEM();
        }
    }
}
